import base64
import json
import pickle
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from goods.models import SKU
import base64


# Create your views here.


class CartsView(View):

    def post(self, request):

        # 接收数据
        json_dict = json.loads(request.body.decode())
        count = json_dict.get('count')
        sku_id = json_dict.get('sku_id')

        try:
            goods = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '商品不存在'})

        try:
            count = int(count)
        except Exception:
            count = 1

        # 获取用户登陆信息
        user = request.user

        if user.is_authenticated:
            # 用户未登录
            redis_cli = get_redis_connection('carts')
            # 用哈希存储数据
            # redis_cli.hset('carts_%s' % user.id, sku_id, count)

            redis_cli.hincrby('carts_%s' % user.id, sku_id, count)
            # 默认选中，存储在集合
            redis_cli.sadd('selected_%s' % user.id, sku_id)

            return JsonResponse({'code': 0})
        else:
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts:
                # 先对加密的数据解密
                carts = pickle.loads(base64.b64decode(cookie_carts))
            else:
                #     5.1 先有cookie字典
                carts = {}

            # 判断新增的商品 有没有在购物车里
            if sku_id in carts:
                # 购物车中 已经有该商品id
                # 数量累加
                ## {16： {count:3,selected:True}}
                origin_count = carts[sku_id]['count']
                count += origin_count

            carts[sku_id] = {
                sku_id: {'count': count, 'selected': True}
            }

            # carts[sku_id] = {
            #     'count': count,
            #     'selected': True
            # }

            # 字典数据转换成bytes
            carts_bytes = pickle.dumps(carts)

            base64encode = base64.b64encode(carts_bytes)

            response = JsonResponse({'code': 0})

            response.set_cookie('carts', base64encode.decode(), max_age=3600 * 24 * 12)

            return response



    def get(self, request):

        # 1、判断用户是否登陆
        user = request.user
        if user.is_authenticated:
        # 2、登陆用户查询redis
            redis_cli = get_redis_connection('carts')
            sku_id_counts = redis_cli.hgetall('carts_%s' % user.id)     # 商品id,商品数量
            selected_ids = redis_cli.smembers('selected_%s' % user.id)  # 商品的选中状态
        # 2.4 将 redis的数据转换为 和 cookie一样
        # 这样就可以在后续操作的时候 统一操作
        # {sku_id:{count:xxx,selected:xxx}}
            carts = {}

            for sku_id, count in sku_id_counts.items():
                carts[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in selected_ids
                }

        else:
            # 3、未登录用户查询cookie
            carts_cookies = request.COOKIES.get('carts')
            if carts_cookies is None:
                carts = {}
            else:
                carts = pickle.loads(base64.b64decode(carts_cookies))

        # {sku_id: {count: xxx, selected: xxx}}
        # 4 根据商品id查询商品信息
        # 可以直接遍历 carts
        # 也可以获取 字典的最外层的key，最外层的所有key就是商品id
        sku_ids = carts.keys()
        # [1,2,3,4,5]
        # 可以遍历查询
        # 也可以用 in
        skus = SKU.objects.filter(id__in=sku_ids)

        sku_list = []
        for sku in skus:
        # 5 将对象数据转换为字典数据
            sku_list.append({
                'id': sku.id,
                'price': sku.price,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'selected': carts[sku.id]['selected'],  # 选中状态
                'count': int(carts[sku.id]['count']),  # 数量 强制转换一下
                'amount': sku.price * carts[sku.id]['count']  # 总价格
            })
            # 6 返回响应
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': sku_list})





    # def put(self, request):
    #
    #     # 确定修改用户
    #     user = request.user
    #
    #     json_dict = json.loads(request.body.decode())
    #     sku_id = json_dict.get('sku_id')
    #     count = json_dict.get('count')
    #     selected = json_dict.get('selected')
    #
    #     if not all([sku_id, count]):
    #         return JsonResponse({'code': 400, 'errmsg': '参数不全'})
    #
    #     try:
    #         skus = SKU.objects.get(id=sku_id)
    #     except Exception:
    #         return JsonResponse({'code': 400, 'errmsg': '商品不存在'})
    #     try:
    #         count = int(count)
    #     except Exception:
    #         count = 1
    #
    #     # 登陆用户更新redis
    #     if user.is_authenticated:
    #         redis_cli = get_redis_connection('carts')
    #         # 从redis中取出参数
    #         redis_cli.hset('carts_%s' % user.id, sku_id, count)  # 商品id,商品数量
    #
    #         if selected:
    #             redis_cli.sadd('selected_%s' % user.id, sku_id)
    #
    #         else:
    #             redis_cli.srem('selected_%s' % user.id, sku_id)
    #
    #             # 返回响应
    #             return JsonResponse({'code': 0, 'cart_sku': {'selected': selected, 'count': count}})
    #
    #     else:
    #         # 未登录用户更新cookie
    #         carts_cookie = request.COOKIES.get('carts')
    #         if carts_cookie is not None:
    #             carts = pickle.loads(base64.b64decode(carts_cookie))
    #         else:
    #             carts = {}
    #
    #             # 取出cookie携带的参数
    #         if sku_id in carts:
    #             carts[sku_id] = {
    #                 'count': count,
    #                 'selected': selected
    #             }
    #             #     5.3 重新最字典进行编码和base64加密
    #         new_carts = base64.b64encode(pickle.dumps(carts))
    #         #     5.4 设置cookie
    #         response = JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': {'count': count, 'selected': selected}})
    #         response.set_cookie('carts', new_carts.decode(), max_age=14 * 24 * 3600)
    #         #     5.5 返回响应
    #         return response

    def put(self, request):
        # 1.获取用户信息
        user = request.user
        # 2.接收数据
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected')
        # 3.验证数据
        if not all([sku_id, count]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': '没有此商品'})

        try:
            count = int(count)
        except Exception:
            count = 1

        if user.is_authenticated:
            # 4.登录用户更新redis
            #     4.1 连接redis
            redis_cli = get_redis_connection('carts')
            #     4.2 hash
            redis_cli.hset('carts_%s' % user.id, sku_id, count)
            #     4.3 set
            if selected:
                redis_cli.sadd('selected_%s' % user.id, sku_id)
            else:
                redis_cli.srem('selected_%s' % user.id, sku_id)
            #     4.4 返回响应
            return JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': {'count': count, 'selected': selected}})

        else:
            # 5.未登录用户更新cookie
            #     5.1 先读取购物车数据
            cookie_cart = request.COOKIES.get('carts')
            #         判断有没有。
            if cookie_cart is not None:
                #         如果有则解密数据
                carts = pickle.loads(base64.b64decode(cookie_cart))
            else:
                #         如果没有则初始化一个空字典
                carts = {}

            #     5.2 更新数据
            # {sku_id: {count:xxx,selected:xxx}}
            if sku_id in carts:
                carts[sku_id] = {
                    'count': count,
                    'selected': selected
                }
            #     5.3 重新最字典进行编码和base64加密
            new_carts = base64.b64encode(pickle.dumps(carts))
            #     5.4 设置cookie
            response = JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': {'count': count, 'selected': selected}})
            response.set_cookie('carts', new_carts.decode(), max_age=14 * 24 * 3600)
            #     5.5 返回响应
            return response



    def delete(self, request):

        user = request.user
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')

        try:
            carts = SKU.objects.get(id=sku_id)
        except Exception:
            return JsonResponse({'code': 0, 'errmsg': '商品不存在'})

        # 验证用户登陆
        if user.is_authenticated:
            # 用户登陆，走redis
            redis_cli = get_redis_connection('carts')
            redis_cli.hdel('carts_%s' % user.id, sku_id)
            redis_cli.srem('selected_%s' % user.id, sku_id)

            return JsonResponse({'code': 0, 'errmsg': 'ok'})

        else:
            carts_cookie = request.COOKIES.get('carts')
            if carts_cookie:
                carts = {}
            else:
                carts = pickle.loads(base64.b64decode(carts_cookie))

            del carts[sku_id]
            #     5.3 我们需要对字典数据进行编码和base64的处理
            new_carts = base64.b64encode(pickle.dumps(carts))
            #     5.4 设置cookie
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('carts', new_carts.decode(), max_age=14 * 24 * 3600)
            #     5.5 返回响应
            return response


            pass











